#include "drvSpi.h"
#include "stm32g0xx_hal.h"

int drvSpiInit(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    __HAL_RCC_GPIOA_CLK_ENABLE();
    /*
    *SPI1 GPIO Configuration
    PA5     ------> SPI1_SCK
    PA7     ------> SPI1_MOSI
    PB0     ------> SPI1_CS
    */
    GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_0;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    return 0;
}

int drvSpiDeInit(void)
{
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_5 | GPIO_PIN_7);
    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_0);
    return 0;
}

#define drvSpiCsClr() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET)
#define drvSpiCsSet() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET)
#define drvSpiMosiClr() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_RESET)
#define drvSpiMosiSet() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_SET)
#define drvSpiSckClr() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET)
#define drvSpiSckSet() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET)

void delay_us(uint32_t nus)
{
    for(volatile uint32_t i = 0; i < nus;i++)
        for(volatile uint32_t j = 0;j < 1;j++);
}  

void drvSpiWReg(uint8_t reg)
{
    uint8_t i = 0;
    drvSpiCsClr();
    drvSpiMosiClr();
    drvSpiSckClr();
    delay_us(1);
    drvSpiSckSet();
    for(i = 0; i < 8; i++) {
        if (reg & 0x80)
            drvSpiMosiSet();
        else
            drvSpiMosiClr();
        drvSpiSckClr();
        delay_us(1);
        drvSpiSckSet();
        reg <<= 1;
    }
    drvSpiCsSet();
}

void drvSpiWByte(uint8_t dat)
{
    uint8_t i = 0;
    drvSpiCsClr();
    drvSpiMosiSet();
    drvSpiSckClr();
    delay_us(1);
    drvSpiSckSet();
    for (i = 0; i < 8; i++) {
        if (dat & 0x80)
            drvSpiMosiSet();
        else
            drvSpiMosiClr();
        drvSpiSckClr();
        delay_us(1);
        drvSpiSckSet();
        dat <<= 1;
    }
    drvSpiCsSet();
}
